/***************************************************************************
 *   Copyright (C) 2009, 2010 by MJ   *
 *   mj_dv@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

//sourcemod.cpp - is a part from steamserverutil by MJ
//steamserverutil.googlecode.com

//it handles the sourcemod support

#include <iostream> //for cout and cin
#include <fstream> //for ifstream and ofstream
#include <stdlib.h> //for system()
#include <vector>

//for gettext
#include <libintl.h>
#include <locale.h>

#define _(STRING) gettext(STRING)

//#include "sourcemod.h"
#include "steamserverutil.h"
#include "conf_server.h"
#include "metamod.h"


//to make the differance of the arrays better 
#define OFF_N 0
#define OFF_C 1

using namespace std;


void install_sourcemod()
{
	//download link http://sourcemod.tf2couch.com/sourcemod-1.2.4.tar.gz
	cout << _("\n\nIn which server do you want to install sourcemod?\n\n");

	int choice = choose_dialog();
	
	if(choice == -1)
		return;

	string params; //the hole command is saved here



	params = "cd "; //because in function mani_test the "cd " is not included
	param.clear();

	
	//if it is really installed
	installed = false;
	metamod_test(server[choice]);
	params += param;
	//-------end---------(modified)
	
	if(!is_metamod_installed(params))
	{
		cout << _("\nmetamod must be installed first!\nInstall now?(y/n) ");
		char choice;
		cin >> choice;
		
		if(choice == 'y')
			install_metamod();
		else
			return;
	}


	if(installed==true)
	{
		
			
		cout << endl << endl << _("Downloading sourcemod with wget, unzipping archive...") << endl << endl;
		params += " && wget http://sourcemod.tf2couch.com/sourcemod-1.3.0.tar.gz && ";
		

		//to download sourcemod

		//--atime-preserve=system 

		params += "tar -xzf sourcemod-1.3.0.tar.gz ";
		//to "unzip" sourcemod (unzips automatically in right folder)

		try 
		{
			system_check(system(params.c_str()));
		}
		catch(int e) {}
		
		ofstream save_vdf;

		cout << _("\n\nCreating metamod.vdf\n");
		
		param += "/addons/metamod.vdf";
		
		save_vdf.open(param.c_str()); //right path
		
		//with choice right entry
		switch (server[choice])
		{

			case 1: 
				
				
				save_vdf << "\"Plugin\"\n";
				save_vdf << "{\n";
				save_vdf << " \"file\" \"../cstrike/addons/metamod/bin/server\"\n";
				save_vdf << "}";
				break;

			case 2: 
				
				
				save_vdf << "\"Plugin\"\n";
				save_vdf << "{\n";
				save_vdf << " \"file\" \"../dod/addons/metamod/bin/server\"\n";
				save_vdf << "}";
				break;
				
			case 3: 
				
				save_vdf << "\"Plugin\"\n";
				save_vdf << "{\n";
				save_vdf << " \"file\" \"../garrysmod/addons/metamod/bin/server\"\n";
				save_vdf << "}";
				
				break;

			case 4: 
		
				
				save_vdf << "\"Plugin\"\n";
				save_vdf << "{\n";
				save_vdf << " \"file\" \"../hl2mp/addons/metamod/bin/server\"\n";
				save_vdf << "}";
				break;

			case 5:
				
				save_vdf << "\"Plugin\"\n";
				save_vdf << "{\n";
				save_vdf << " \"file\" \"../tf/addons/metamod/bin/server\"\n";
				save_vdf << "}"; 
				break;



				default: never_happen();
				break;

		}
		
		save_vdf.close();


		cout << _("\n\nSourceMod succesfully installed!\n");
		

	}
}

void deactivate_sourcemod()
{
	cout << _("\n\nFrom which server do you wish to deactivate sourcemod? \n");
	
	int choice = choose_dialog();
	
	if(choice == -1)
		return;

	string params;


	params += "cd "; //the "cd " is not include by mani_test(int)
	
	//if it is really installed	
	installed = false;
	metamod_test(server[choice]);
	params += param;
	//-------end---------(modified)


	

	if(installed==true)
	{
		cout << _("\n\nDeactivating source...\nDeleting sourcemod.vdf");
		params += " && rm -rf addons/sourcemod.vdf";


		try 
		{
			system_check(system(params.c_str()));
		}
		catch(int e) {}
	}
}

//TODO this is only admins_simple.ini
//there is another file called admins.cfg
void admin_sourcemod()
{
	string params;
	bool exit = false;

	cout << _("From which server do you wish to edit the admins?\n");

	int choice = choose_dialog();
	
	if(choice == -1)
		return;

	//if it is really installed	
	installed = false;
	metamod_test(server[choice]);
	params += param;
	//-------end---------

	
	//OFF_name means 0, OFF_C means 1	
	


	

	if(installed==true)
	{

	
		params += "/addons/sourcemod/configs/admins_simple.ini";
		


		


		while (!exit)
		{

			unsigned short int counter = 0;
			
			vector<string> buf[2];
			
			ifstream in;
			in.open(params.c_str());

			if(in.is_open())
			{
			

				cout << _("\n\nCurrent admins: \n");
				cout << _("   \tID\t:: Flags\n");


				while(!in.eof())
				{
					
					getline(in, temp);
				
					switch(temp[0])
					{
						case '"': int i;
						
						//force a new string in the vector
						buf[OFF_N].push_back("");
						buf[OFF_C].push_back("");
						
						for(i=1; i<temp.size(); i++)
						{
							if(temp[i]=='"')
								break;

							buf[OFF_N][counter] += temp[i];
						}

						buf[OFF_N][counter] += '\0'; //0 means end of string

						i+=2; //to junp over the '"' and over the ' '

						
						for(; i<temp.size(); i++)
						{
							if((temp[i]=='/' && temp[(i+1)] == '/') || temp[i] == 0) //0 means end of string
								break;

							buf[OFF_C][counter] += temp[i];
						}

							  
						buf[OFF_C][counter] += '\0'; //0 means end of string
							  
						cout << (counter+1) << ".\t" << buf[OFF_N][counter] << "\t:: " << buf[OFF_C][counter];
						
						counter++;
							  
						temp.clear(); //clearing, to avoid the bug with the letter when temp[] = "\"\" "
						
						break;
						
						case 10: //10 means new line
							//nothing to do
							break;
						case 0://0 means end of string
							//nothing to do
							break;
							
						case '/': if (temp[1] == '/')
								break;

						default: break;
							
					}
				
				}

				in.close();

			}
		
			else
				cout << _("\nYou have no admins, please add one!\n");

		
		

			cout << _("\n\n1. Add admin\n");
			cout << _("2. Delete admin\n");
			cout << _("3. Edit a admin\n");
			cout << _("4. Delete hole list\n");
			cout << _("5. Exit\n");


			cout << " : ";
			cin >> choice;
			cin.ignore();


			switch(choice)
			{
				case 1: cout << _("\nSteam ID: ");
				{
					string id;
					getline(cin, id);

					cout << _("\nPlease set the flags of the admin, if no flags are set, the admin has all rights! (flag z)\n");
					cout << _("\nFlags: ");
					string flags;
					getline(cin, flags);

					ofstream out;
					out.open(params.c_str(), ios_base::app);
					
					if(flags.length() == 0)
						flags = "z";
					out << endl << "\"" << id << "\"" << " \"" << flags << "\"";
					out.close();
				}
				break;

			
				case 2: cout << _("\n\nWhich entry do you want do delete? ");
				cin >> choice;
		
				choice--;

				if(choice >= counter)
				{
					cout << _("\nThis entry does not exist!\n\n");
				}
				else
				{

					ofstream save_del;
					save_del.open(params.c_str());

					buf[OFF_N].erase(buf[OFF_N].begin() + choice);
					buf[OFF_C].erase(buf[OFF_C].begin() + choice);

					//		OFF_C, OFF_N should be same size
					for (int i = 0;i<buf[OFF_C].size();i++)
						save_del << endl << "\"" << buf[OFF_N][i] << "\"" << " \"" << buf[OFF_C][i] << "\"";
						
							
					
					save_del.close();
				}
				break;


				case 3:	cout << _("\nWhich entry do you wish do edit? ");
				cin >> choice;
					
				choice--; //for thr right array


				if (choice >= counter)
				{
					cout << _("\n\nThis entry does not exist!\n\n");
				}
				else
				{
					cout << _("\n\n1. Edit the Steam ID\n");
					cout << _("2. Edit the flags\n");
					cout << " : ";
					unsigned short int temp_e;
					cin >> temp_e;
					cin.ignore();

					if(temp_e > 2)
					{
						cout << _("\n\nWrong choice!\n");
					}
					else
					{
						temp_e--;  //for the right array
						cout << _("\nNew ID/flags: ");
						getline(cin, buf[temp_e][choice]);

	

						ofstream save_edit;
						save_edit.open(params.c_str());


						//		OFF_C, OFF_N should be same size
						for (int i = 0;i<buf[OFF_N].size();i++)
							save_edit  << "\"" << buf[OFF_N][i] << "\"" << " " << buf[OFF_C][i] << endl;

				
						
					}

				}

				break;


				case 4: char temp;
				cout << _("\n\nThe hole admins are going to be deleted. Are you sure?(y|n) ");
				cin >> temp;
					

				if(temp=='y')
				{
					ofstream del_all;
					del_all.open(params.c_str());
					del_all.close();
				}
				break;
				case 5: exit = true;
				break;
				default: cout << _("\n\nTry again;)\n");
			}
		}
	}
}

void bans_sourcemod()
{
	string params;
	bool exit = false;

	cout << _("From which server do you wish to edit the admins?\n");

	int choice = choose_dialog();
	
	if(choice == -1)
		return;

	//if it is really installed	
	installed = false;
	metamod_test(server[choice]);
	params += param;
	//-------end---------
	
	if(installed==true)
	{
		params += "/cfg/banned_user.cfg";
		
		//TODO: add content HERE !
	}
}

void sm_menu()
{
	string params;
	bool exit = false;

	cout << _("From which server do you wish to edit the admins?\n");

	int choice = choose_dialog();
	
	if(choice == -1)
		return;

	//if it is really installed	
	installed = false;
	metamod_test(server[choice]);
	params += param;
	//-------end---------
	
	if(installed==true)
	{
		params += "/addons/sourcemod/configs/adminmenu_sorting.txt";
		
		while (!exit)
		{

			vector<string> playerCommands;
			vector<string> serverCommands;
			vector<string> votingCommands;
			
			ifstream in;
			in.open(params.c_str());
			
			

			if(in.is_open())
			{
				while(!in.eof())
				{
					getline(in, temp);
					if(temp.find("Menu") != string::npos)
						break;
				}
				
				//Now we begin with looking for content
				
				while(!in.eof())
				{
					getline(in, temp);
					
					if(temp.find("\"PlayerCommands\"") != string::npos)
					{
						//we found it
						cout << _("\n\nPlayer Commands:\n");
						
						bool break_loop = false;
						
						while(!in.eof())
						{
							
							if(!break_loop)
								getline(in, temp);
							else
								break; //breaking here because "}" detected
							
							if(temp.find("{") == string::npos)
								continue;
							
							if(temp.find("}") != string::npos)
								break; //end of section
							
							//found again
							//reading items now
							
							int counter = 0;

							while(!in.eof())
							{
								getline(in, temp);
								
								int pos = temp.find("\"");
								
								
								if(pos == string::npos)
								{
									if(temp.find("}") != string::npos)
									{
										break_loop = true;
										break;
									}
									else
										continue;
								}
								
								playerCommands.push_back("");
								
								//"item"   "sm_command"
								//remove "item" and jump to the sm_command
								
								pos++;
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;
								}
								
								
								pos++;
								//find new \" position
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;
								}
								
								pos++;
								//command is saved now
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;

									playerCommands[counter] += temp[pos];
									
								}
								
								
								
								//playerCommands[counter] += '\0'; //0 means end of string
								
								cout << (counter+1) << ".\t" << playerCommands[counter] << "\n";
								
								counter++;

							}
						}
						
						continue;
					}
					
					if(temp.find("\"ServerCommands\"") != string::npos)
					{
						//we found it
						
						cout << _("Server commands:\n");
						bool break_loop = false;
						
						while(!in.eof())
						{
							if(!break_loop)
								getline(in, temp);
							else
								break; //breaking here because "}" detected
							
							if(temp.find("{") == string::npos)
								continue;
							
							if(temp.find("}") != string::npos)
								break; //end of section
							
							//found again
							//reading items now
							
							int counter = 0;
							
							while(!in.eof())
							{
								getline(in, temp);
								
								
								int pos = temp.find("\"");

								if(pos == string::npos)
								{
									if(temp.find("}") != string::npos)
									{
										break_loop = true;
										break;
									}
									else
										continue;
								}
								
								serverCommands.push_back("");
								
								
								//"item"   "sm_command"
								//remove "item" and jump to the sm_command
								
								pos++;
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;
								}
								
								
								pos++;
								//find new \" position
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;
								}
								
								pos++;
								//command is saved now
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;

									serverCommands[counter] += temp[pos];
									
								}
								
								//serverCommands[counter] += '\0'; //0 means end of string
								
								cout << (counter+1) << ".\t" << serverCommands[counter] << "\n";
							
								counter++;

							}
						}
						
						continue;
					}
					
					if(temp.find("\"VotingCommands\"") != string::npos)
					{
						//we found it
						
						cout << _("Voting commands:\n");
						bool break_loop = false;
						
						while(!in.eof())
						{
							if(!break_loop)
								getline(in, temp);
							else
								break; //breaking here because "}" detected
							
							if(temp.find("{") == string::npos)
								continue;
							
							if(temp.find("}") != string::npos)
								break; //end of section
							
							//found again
							//reading items now
							
							int counter = 0;
							
							while(!in.eof())
							{
								getline(in, temp);
								
								int pos = temp.find("\"");
								
								if(pos == string::npos)
								{
									if(temp.find("}") != string::npos)
									{
										break_loop = true;
										break;
									}
									else
										continue;
								}
								
								votingCommands.push_back("");
								
								//"item"   "sm_command"
								//remove "item" and jump to the sm_command
								
								pos++;
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;
								}
								
								
								pos++;
								//find new \" position
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;
								}
								
								pos++;
								//command is saved now
								for(pos; pos<temp.size(); pos++)
								{
									if(temp[pos]=='"')
										break;

									votingCommands[counter] += temp[pos];
									
								}
								
								//votingCommands[counter] += '\0'; //0 means end of string
								
								cout << (counter+1) << ".\t" << votingCommands[counter] << "\n";
								
								
								counter++;

							}
						}
						
						continue;
					}
				}
			}
			else
				cerr << _("\n\nNo menu config!!\n");
			
			in.close();
			
			int which_command;
			cout << _("\n\n1. Configure Player Commands\n");
			cout << _("2. Configure Server Commands\n");
			cout << _("3. Configure Voting Commands\n");
			cout << _("4. Exit\n");
			cout << " : ";
			cin >> which_command;
			cin.ignore();
			
			if(which_command >= 4 || which_command < 1)
			{
				exit=true;
				continue;
			}
			
			
			cout << _("\n\n1. Add Item\n");
			cout << _("2. Edit Item\n");
			cout << _("3. Move up\n");
			cout << _("4. Move down\n");
			cout << _("5. Delete Item\n");
			cout << _("6. Exit\n");
				
			int choice;
			cout << " : ";
			cin >> choice;
			cin.ignore();
			
			switch(choice)
			{
				case 1: cout << _("\nPlease enter new item: ");
					getline(cin, temp);
					
					switch(which_command)
					{
						case 1: playerCommands.push_back(temp);
							break;
							
						case 2: serverCommands.push_back(temp);
							break;
							
						case 3: votingCommands.push_back(temp);
							break;
					}
					
					break;
					
				case 2: cout << _("\nWhich item should be edited? ");
					cin >> choice;
					cin.ignore();
					
					choice--;
					
					cout << _("\nPlease enter new item: ");
					getline(cin, temp);
					
					switch(which_command)
					{
						case 1: if(choice > playerCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							playerCommands[choice] = temp;
							break;
							
						case 2: if(choice > serverCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							serverCommands[choice] = temp;
							break;
							
						case 3: if(choice > votingCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							votingCommands[choice] = temp;
							break;
					}
					
					break;
					
				case 3: cout << _("\n\nWhich enty do you want to move up?\n : ");
					cin >> choice;
					cin.ignore();
					choice--;
					
					if(choice == 0)
					{
						cout << _("\nSorry, this item cannot be moved!\n\n");
						break;
					}
					
					
					
					switch(which_command)
					{
						case 1: if(choice > playerCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							temp = playerCommands[choice];
							playerCommands[choice] = playerCommands[choice - 1];
							playerCommands[choice - 1] = temp;
							break;
							
						case 2: if(choice > serverCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							temp = serverCommands[choice];
							serverCommands[choice] = serverCommands[choice - 1];
							serverCommands[choice - 1] = temp;
							break;
							
						case 3: if(choice > votingCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							temp = votingCommands[choice];
							votingCommands[choice] = votingCommands[choice - 1];
							votingCommands[choice - 1] = temp;
							break;
					}
					
					break;
					
					
				case 4: cout << _("\n\nWhich enty do you want to move down?\n : ");
					cin >> choice;
					cin.ignore();
					choice--;

					
					switch(which_command)
					{
						case 1: if(choice > playerCommands.size())
						{	
							cout << _("\n\nEntry does not exist!\n\n");
							break;
						}
						temp = playerCommands[choice];
						playerCommands[choice] = playerCommands[choice + 1];
						playerCommands[choice + 1] = temp;
						break;
							
						case 2: if(choice > serverCommands.size())
						{	
							cout << _("\n\nEntry does not exist!\n\n");
							break;
						}
						temp = serverCommands[choice];
						serverCommands[choice] = serverCommands[choice + 1];
						serverCommands[choice + 1] = temp;
						break;
							
						case 3: if(choice > votingCommands.size())
						{	
							cout << _("\n\nEntry does not exist!\n\n");
							break;
						}
						temp = votingCommands[choice];
						votingCommands[choice] = votingCommands[choice + 1];
						votingCommands[choice + 1] = temp;
						break;
					}
					
					break;
					
				case 5: cout << _("\nWhich item should be removed? ");
					cin >> choice;
					cin.ignore();
					
					choice--;
					
					switch(which_command)
					{
						case 1: if(choice > playerCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							playerCommands.erase(playerCommands.begin() + choice);
							break;
							
						case 2: if(choice > serverCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							serverCommands.erase(serverCommands.begin() + choice);
							break;
							
						case 3: if(choice > votingCommands.size())
							{	
								cout << _("\n\nEntry does not exist!\n\n");
								break;
							}
							votingCommands.erase(votingCommands.begin() + choice);
							break;
					}
					
					break;
					
				
				case 6: exit=true;
					break;
				
				default: cout << _("\n\nWrong choice!\n\n");
				
			}
			
			
			ofstream out(params.c_str());
			
			if(!out.is_open())
				continue;
			
			out << "\"Menu\"\n";
			out << "{\n";
			out << "\t\"PlayerCommands\"\n";
			out << "\t{\n";
			
			for(int i = 0; i < playerCommands.size(); i++)
				out << "\t\t\"item\"\t\"" << playerCommands[i] << "\"\n";
			
			out << "\t}\n";
			
			out << "\t\"ServerCommands\"\n";
			out << "\t{\n";
			
			for(int i = 0; i < serverCommands.size(); i++)
				out << "\t\t\"item\"\t\"" << serverCommands[i] << "\"\n";
			
			out << "\t}\n";
			
			out << "\t\"VotingCommands\"\n";
			out << "\t{\n";
			
			for(int i = 0; i < votingCommands.size(); i++)
				out << "\t\t\"item\"\t\"" << votingCommands[i] << "\"\n";
			
			out << "\t}\n";
			out << "}\n";
			out.close();
			
		}
		
	}
	
}

//in addons/sourcemod/configs
void sm_admingroups()
{}

void sm_adminmenu_grouping()
{}

void sm_adminlevel()
{}

void sm_adminmenu_configs()
{}

void sm_custom_adminmenu_commands()
{}

void sm_core_config()
{}

void sm_maplist()
{}

void sm_pluginsettings()
{}

//in cstrike/cfg/sourcemod
void sm_funcommands()
{}

void sm_warmode()
{}

void sm_cfg()
{}

void config_sourcemod()
{
	bool exit=false;

	while(!exit)
	{
		unsigned short int choice;
		cout << _("\n\n1. Install sourcemod\n");
		cout << _("2. Deactivate sourcemod\n");
		cout << _("3. Configure Admins\n");
		cout << _("4. Configure Bans\n");
		cout << _("5. Configure Admin Menu\n");
		cout << _("6. Configure Groups\n");
		cout << _("7. Core Configuration\n");
		cout << _("8. Configure cfg\n");
		cout << _("9. Configure maps\n");
		cout << _("10. Configure plugin settings\n");
		cout << _("11. Configure Fun Commands\n");
		cout << _("12. Configure War Mode\n");
		cout << _("13. Configure cfg\n");
		cout << _("14. Back\n");
		cout << " : ";
		cin  >> choice;	

		switch(choice)
		{
			case 1: install_sourcemod();
			break;
			case 2: deactivate_sourcemod();
			break;
			case 3: admin_sourcemod();
			break;
			case 4: bans_sourcemod();
			break;
			case 5: sm_menu();
			break;
			case 6: sm_admingroups();
			break;
			case 7: sm_core_config();
			break;
			case 8: sm_cfg();
			break;
			case 9: sm_maplist();
			break;
			case 10: sm_pluginsettings();
			break;
			case 11: sm_funcommands();
			break;
			case 12: sm_warmode();
			break;
			case 13: sm_cfg();
			break;
			case 14: exit=true;
			break;
			default: cout << _("\n\nWrong choice. Try again;)");
			break;
		}
	}
}

